﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;


/// <summary>
/// Assessment class which contains the test questions. Serializable for storage in the database.
/// </summary>
[Serializable()]
public class Assessment : ISerializable
{
    private int _id;
    private string _name;
    private DateTime _createdDate;
    private List<Question> _questions;
    private string _html;
    private string _xml;

    public Assessment()
    {
        _questions = new List<Question>();
    }

    /// <summary>
    /// Returns HTML representation of the assessment
    /// </summary>
    /// <returns>Assessment as HTML string</returns>
     public string getAssessmentHtml()
    {
        buildHtml(false);
        return this._html;
    }

     /// <summary>
     /// Returns XML representation of the assessment
     /// </summary>
     /// <returns>Assessment as XML string</returns>
     public string getAssessmentHtmlWithAnswers()
     {
         buildHtml(true);
         return this._html;
     }

     /// <summary>
     /// Returns HTML representation of the assessment
     /// </summary>
     /// <returns>Assessment as HTML string</returns>
     public string getAssessmentXml()
     {
         buildXML(false);
         return this._xml;
     }

     /// <summary>
     /// Returns XML representation of the assessment
     /// </summary>
     /// <returns>Assessment as XML string</returns>
     public string getAssessmentXmlWithAnswers()
     {
         buildXML(true);
         return this._xml;
     }

     private void buildHtml(bool includeAnswers)
     {
         StringBuilder sb = new StringBuilder();

         sb.Append("<div id=\"assessment\">");
         sb.Append("<span id=\"name\">" + _name + "</span>");
         sb.Append("<span id=\"assessmentId\">" + _id + "</span>");
         sb.Append("<span id=\"date\">" + _createdDate.ToString("MM/dd/yyyy HH:mm:ss") + "</span>");
         foreach (Question question in _questions)
         {
             if(includeAnswers)
                 sb.Append(question.getQuestionWithAnswerHtml());
             else
                 sb.Append(question.getQuestionHtml());
         }
         sb.Append("</div>");
         this._html = sb.ToString();
     }

     private void buildXML(bool includeAnswers)
     {
         StringBuilder sb = new StringBuilder();

         sb.Append("<assessment>");
         sb.Append("<name>" + _name + "</name>");
         sb.Append("<assessmentId>" + _id + "</assessmentId>");
         sb.Append("<date>" + _createdDate.ToString("MM/dd/yyyy HH:mm:ss") + "</date>");
         foreach (Question question in _questions)
         {
             if (includeAnswers)
                 sb.Append(question.getQuestionWithAnswerXml());
             else
                 sb.Append(question.getQuestionXml());
         }
         sb.Append("</assessment>");
         this._xml = sb.ToString();
     }

    [DataMember]
    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public DateTime CreatedDate
    {
        get { return _createdDate; }
        set { _createdDate = value; }
    }

    public void addQuestion(Question newQuestion)
    {
        _questions.Add(newQuestion);   
    }

    public string getGrade(string answers)
    {
        int numberOfQuestions = _questions.Count;
        decimal cumulativeTotal = 0;

        int i = 0;
        string[] answersSplit = answers.Split('|');
        foreach(string answer in answersSplit)
        {
            if (_questions[i++].getCorrectAnswer() == answer)
                cumulativeTotal++;
        }

        decimal finalGradePercent = cumulativeTotal / numberOfQuestions;
        return finalGradePercent.ToString();
    }

    /// <summary>
    /// Deserialization constructor
    /// </summary>
    /// <param name="info"></param>
    /// <param name="ctxt"></param>
    public Assessment(SerializationInfo info, StreamingContext ctxt)
    {
        _id = (int)info.GetValue("_id", typeof(int));
        _name = (String)info.GetValue("_name", typeof(String));
        _questions = (List<Question>)info.GetValue("_questions", typeof(List<Question>));
        _createdDate = (DateTime)info.GetValue("_createdDate", typeof(DateTime));

    }

    /// <summary>
    /// Serialization function
    /// </summary>
    /// <param name="info"></param>
    /// <param name="ctxt"></param>
    public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
    {
        info.AddValue("_id", _id);
        info.AddValue("_name", _name);
        info.AddValue("_questions", _questions);
        info.AddValue("_createdDate", _createdDate);
    }
}
